package fr.webeo.teambuilder.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import fr.webeo.teambuilder.ao.FootModel;
import fr.webeo.teambuilder.ao.MyTableModel;
import fr.webeo.teambuilder.ao.TableSorter;
import fr.webeo.teambuilder.bo.Player;
import fr.webeo.teambuilder.bo.Team;

/**
 * The class <strong>FootPanel</strong>.
 * 
 * @author Sébastien Bordes
 * @version $Revision$ $Date$ $Name$
 * 
 * @since fr.webeo.teambuilder 1.0
 */
public class FootPanel extends AbstractPanel implements ActionListener, MouseListener, ItemListener {

    /**
     * Comment for <code>serialVersionUID</code>
     */
    private static final long serialVersionUID = 5476744369491944414L;

    private static final String playerForNTeamLB = "Organiser en {0} �quipes";

    private static final String teamForNPlayerLB = "Organiser en �quipes de {0}";

    private JTable tableau;

    private JList equipeA;

    private JList equipeB;

    private JPopupMenu menu;

    private JPanel participant;

    private JButton organizePlayerForNTeam;

    private JComboBox playerForNTeamCBB;

    private int organizeCount;

    private JButton organizeTeamForNPlayer;

    private JComboBox teamForNPlayerCBB;

    private final int organizeCount2;

    private JButton export;

    private JButton export2;

    private JButton swap;

    private JTabbedPane teamTP;

    /** */
    private PlayerForNTeamPanel playerForNTeamPanel;

    /** */
    private TeamForNPlayerPanel teamForNPlayerPanel;

    public FootPanel(boolean mode) {
        super(new FootModel(mode));
        this.organizeCount = 0;
        this.organizeCount2 = 0;
    }

    public FootPanel(boolean mode, URL codeBase) {
        super(new FootModel(mode));
        this.organizeCount = 0;
        this.organizeCount2 = 0;
        getModel().setCodeBase(codeBase);
    }

    private JPanel getTablePanel() {
        if (this.participant == null) {
            this.participant = new JPanel(new BorderLayout());
            TableSorter sorter = new TableSorter(getModel().getTableModel());
            this.tableau = new JTable(sorter);
            sorter.setTableHeader(this.tableau.getTableHeader());
            sorter.setSortingStatus(0, -1);

            MyCellRenderer mcr = new MyCellRenderer();
            this.tableau.getColumn(MyTableModel.NAME_COL_READY).setCellRenderer(mcr);
            this.tableau.getColumn(MyTableModel.NAME_COL_NOM).setCellRenderer(mcr);
            this.tableau.getColumn(MyTableModel.NAME_COL_PRENOM).setCellRenderer(mcr);
            this.tableau.getColumn(MyTableModel.NAME_COL_MAIL).setCellRenderer(mcr);
            this.tableau.getColumn(MyTableModel.NAME_COL_EQUIPE).setCellRenderer(mcr);
            this.tableau.getColumn(MyTableModel.NAME_COL_COEQUIPIER).setCellRenderer(mcr);
            JCheckBox cb = new JCheckBox();
            cb.setHorizontalAlignment(0);
            DefaultCellEditor dcc = new DefaultCellEditor(cb);
            this.tableau.getColumn("Ready").setCellEditor(dcc);
            JTextField tf = new JTextField();
            DefaultCellEditor dce = new DefaultCellEditor(tf);
            tf.setHorizontalAlignment(0);
            this.tableau.getColumn("Nom").setCellEditor(dce);
            this.tableau.getColumn("Pr\351nom").setCellEditor(dce);
            this.tableau.getColumn("eMail").setCellEditor(dce);

            JComboBox cbb = new JComboBox();
            cbb.addItem("");
            cbb.addItem("Equipe A");
            cbb.addItem("Equipe B");
            DefaultCellEditor dcbb = new DefaultCellEditor(cbb);
            this.tableau.getColumn("Pr\351f\351rence").setCellEditor(dcbb);

            JComboBox cbb2 = new JComboBox();
            cbb2.addItem("");

            for (int i = 0; i < getModel().getTableModel().getRowCount(); i++) {
                cbb2.addItem((getModel().getTableModel().getValueAt(i)));
            }

            DefaultCellEditor dcbb2 = new DefaultCellEditor(cbb2);
            this.tableau.getColumn(MyTableModel.NAME_COL_COEQUIPIER).setCellEditor(dcbb2);

            this.tableau.setAutoscrolls(true);
            this.tableau.setShowHorizontalLines(false);
            this.tableau.setGridColor(Color.GRAY);
            this.tableau.getColumn("Ready").setPreferredWidth(20);
            this.tableau.getColumn("Nom").setPreferredWidth(150);
            this.tableau.getColumn("Pr\351nom").setPreferredWidth(150);
            this.tableau.getColumn("eMail").setPreferredWidth(250);
            this.tableau.setSelectionMode(0);
            this.tableau.addMouseListener(this);
            JScrollPane jsp = new JScrollPane(this.tableau);
            this.participant.add(jsp, "Center");

            this.participant.add(getOrganizePanel(), "South");
        }
        return this.participant;
    }

    /**
     * <p>
     * TODO To complete.
     * </p>
     * 
     * @since FootPanel 1.0
     */
    private JPanel getOrganizePanel() {
        JPanel organizeBtpanel = new JPanel();
        organizeBtpanel.setLayout(new GridLayout(1, 5));

        Object[] args = { 2 };
        this.organizePlayerForNTeam = new JButton(new MessageFormat(playerForNTeamLB).format(args));
        this.organizePlayerForNTeam.addActionListener(this);
        organizeBtpanel.add(this.organizePlayerForNTeam);

        this.playerForNTeamCBB = new JComboBox(getModel().getComboBoxModel());
        this.playerForNTeamCBB.addItemListener(this);
        this.playerForNTeamCBB.setSelectedIndex(0);
        organizeBtpanel.add(this.playerForNTeamCBB);

        JCheckBox suspensCb = new JCheckBox("Suspens Mode");
        suspensCb.setActionCommand("suspens");
        suspensCb.addActionListener(this);

        organizeBtpanel.add(suspensCb);

        this.organizeTeamForNPlayer = new JButton(new MessageFormat(teamForNPlayerLB).format(args));
        this.organizeTeamForNPlayer.addActionListener(this);
        organizeBtpanel.add(this.organizeTeamForNPlayer);

        this.teamForNPlayerCBB = new JComboBox(getModel().getComboBoxModel());
        this.teamForNPlayerCBB.addItemListener(this);
        this.teamForNPlayerCBB.setSelectedIndex(0);
        organizeBtpanel.add(this.teamForNPlayerCBB);

        return organizeBtpanel;

    }

    private Component getTabbedPanel() {
        this.teamTP = new JTabbedPane();

        this.playerForNTeamPanel = new PlayerForNTeamPanel(getModel().getPlayerForNTeamModel());
        this.teamTP.addTab("2 Equipes", getEquipePanel());

        this.teamForNPlayerPanel = new TeamForNPlayerPanel(getModel().getTeamForNPlayerModel());
        this.teamTP.addTab("N Team", this.teamForNPlayerPanel);
        return this.teamTP;
    }

    private JPanel getEquipePanel() {
        JPanel main = new JPanel(new BorderLayout());
        JPanel label = new JPanel();
        label.setLayout(new GridLayout(1, 2));
        Font f = new Font("serif", 1, 14);
        JLabel equipeALB = new JLabel("Equipe A");
        equipeALB.setFont(f);
        equipeALB.setHorizontalAlignment(0);
        label.add(equipeALB);
        this.swap = new JButton("Echanger 2 joueurs");
        this.swap.setFont(f);
        this.swap.setHorizontalAlignment(0);
        this.swap.addActionListener(this);
        label.add(this.swap);
        JLabel equipeBLB = new JLabel("Equipe B");
        equipeBLB.setFont(f);
        equipeBLB.setHorizontalAlignment(0);
        label.add(equipeBLB);
        main.add(label, "North");
        JPanel equipe = new JPanel();
        equipe.setLayout(new GridLayout(1, 2));
        this.equipeA = new JList();
        this.equipeA.setModel(new DefaultListModel());
        this.equipeA.getSelectionModel().setSelectionMode(0);
        equipe.add(new JScrollPane(equipeA));
        this.equipeB = new JList();
        this.equipeB.setModel(new DefaultListModel());
        this.equipeB.getSelectionModel().setSelectionMode(0);
        equipe.add(new JScrollPane(equipeB));
        main.add(equipe, "Center");
        this.export = new JButton("Exporter les \351quipes");
        this.export.addActionListener(this);
        main.add(this.export, "South");
        return main;
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(this.organizePlayerForNTeam)) {
            this.organizeCount++;
            organize();
            this.teamTP.setSelectedIndex(0);
        }
        if (e.getSource().equals(this.organizeTeamForNPlayer)) {
            getModel().getTeamForNPlayerModel().organize(getModel().getReadyPlayers());
            this.teamTP.setSelectedIndex(1);
        }
        if (e.getSource().equals(this.export))
            export();
        if (e.getSource().equals(this.export2))
            // getModel().export(getModel().getTeams());
            if (e.getSource().equals(this.swap))
                swap();
        if (e.getSource() instanceof JMenuItem)
            getModel().delete(((TableSorter) this.tableau.getModel()).modelIndex(tableau.getSelectedRow()));

        if (e.getActionCommand().equals("suspens")) {
            getModel().setSuspensMode(((JCheckBox) e.getSource()).isSelected());
        }
    }

    private void swap() {
        if (this.equipeA.getSelectedIndex() > -1 && this.equipeB.getSelectedIndex() > -1) {
            Object aa = this.equipeA.getSelectedValue();
            int idxA = this.equipeA.getSelectedIndex();
            Object bb = this.equipeB.getSelectedValue();
            int idxB = this.equipeB.getSelectedIndex();
            ((DefaultListModel) this.equipeA.getModel()).removeElement(aa);
            ((DefaultListModel) this.equipeA.getModel()).insertElementAt(bb, idxA);
            ((DefaultListModel) this.equipeB.getModel()).removeElement(bb);
            ((DefaultListModel) this.equipeB.getModel()).insertElementAt(aa, idxB);
            this.equipeA.setSelectedIndex(idxA);
            this.equipeB.setSelectedIndex(idxB);
        } else {
            JOptionPane.showMessageDialog(this, "Vous devez choisir 2 joueurs \340 permutter", "Pas de permutation possible", 0);
        }
    }

    private void export() {
        File e = new File("Equipes.txt");
        if (!e.exists() || JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(this, "Le fichier des equipes existe d�j� voulez-vous l'�craser ?")) {

            e.delete();

            try {
                if (e.createNewFile()) {
                    FileWriter fw = new FileWriter(e);
                    fw.write("Equipe A\n");
                    fw.write("---------\n");
                    for (int i = 0; i < this.equipeA.getModel().getSize(); i++) {
                        String name = ((Player) this.equipeA.getModel().getElementAt(i)).getFullName();
                        fw.write((new StringBuilder(" ")).append(name).append("\n").toString());
                    }

                    fw.write("\n");
                    fw.write("Equipe B\n");
                    fw.write("---------\n");
                    for (int i = 0; i < this.equipeB.getModel().getSize(); i++) {
                        String name = ((Player) this.equipeB.getModel().getElementAt(i)).getFullName();
                        fw.write((new StringBuilder(" ")).append(name).append("\n").toString());
                    }

                    fw.close();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    /**
     * 
     */
    private void organize() {
        java.util.List<Player> temp = getModel().getReadyPlayers();
        boolean isPair = temp.size() % 2 == 0;

        ((DefaultListModel) this.equipeA.getModel()).removeAllElements();
        ((DefaultListModel) this.equipeB.getModel()).removeAllElements();

        Team teamA = new Team("A");
        Team teamB = new Team("B");

        Vector removeList = new Vector();
        for (int i = 0; i < temp.size(); i++)
            if ((temp.get(i)).isDansEquipeA()) {
                ((DefaultListModel) equipeA.getModel()).addElement(temp.get(i));
                removeList.add(temp.get(i));
                showPlayer(teamA, temp.get(i));
            } else if ((temp.get(i)).isDansEquipeB()) {
                ((DefaultListModel) equipeB.getModel()).addElement(temp.get(i));
                removeList.add(temp.get(i));
                showPlayer(teamB, temp.get(i));
            }

        for (int i = 0; i < removeList.size(); i++)
            temp.remove(removeList.elementAt(i));

        do {
            int l = (getRandomIndex() % temp.size());
            if (this.equipeA.getModel().getSize() <= equipeB.getModel().getSize()) {
                ((DefaultListModel) this.equipeA.getModel()).addElement(temp.get(l));
                showPlayer(teamA, temp.get(l));
                temp.remove(l);
            } else {
                ((DefaultListModel) equipeB.getModel()).addElement(temp.get(l));
                showPlayer(teamB, temp.get(l));
                temp.remove(l);
            }
        } while (isPair && temp.size() > 0 || temp.size() > 1);
        if (temp.size() > 0) {
            String res = (String) JOptionPane.showInputDialog(getTablePanel(), (new StringBuilder("Dans quel \351quipe souhaitez-vous affecter ")).append(temp.get(0)).toString(),
                    "Nombre de joueurs impair", 1, null, new String[] { "Equipe A", "Equipe B" }, "Equipe A");
            if ("Equipe A".equals(res)) {
                ((DefaultListModel) this.equipeA.getModel()).addElement(temp.get(0));
                temp.remove(0);
            } else {
                ((DefaultListModel) this.equipeB.getModel()).addElement(temp.get(0));
                temp.remove(0);
            }
        }
    }

    private void showPlayer(Team teamA, Player player) {
        if (getModel().isSuspensMode()) {
            StringBuilder sb = new StringBuilder();
            sb.append("Equipe ").append(teamA.getName()).append("\n");
            sb.append("-----> ").append(player.getFullName());

            JOptionPane.showMessageDialog(this, sb.toString());
        }
    }

    private int getRandomIndex() {
        long l = Math.round(Math.random() * 10000D);
        return (int) l;
    }

    /**
     * @see fr.webeo.teambuilder.gui.AbstractPanel#getModel()
     */
    @Override
    public FootModel getModel() {
        return (FootModel) super.getModel();
    }

    public void mouseClicked(MouseEvent e) {
        Object source = e.getSource();
        if ((source instanceof JTable) && SwingUtilities.isRightMouseButton(e) && e.getClickCount() == 1 && ((JTable) source).getSelectedRows().length > 0)
            getMenu().show(e.getComponent(), e.getX(), e.getY());
    }

    private JPopupMenu getMenu() {
        if (this.menu == null) {
            this.menu = new JPopupMenu();
            JMenuItem it = new JMenuItem("Supprimer ce participant");
            it.addActionListener(this);
            this.menu.add(it);
        }
        return this.menu;
    }

    public void mousePressed(MouseEvent mouseevent) {
    }

    public void mouseReleased(MouseEvent mouseevent) {
    }

    public void mouseEntered(MouseEvent mouseevent) {
    }

    public void mouseExited(MouseEvent mouseevent) {
    }

    @Override
    public void init() {
        setLayout(new BorderLayout());
        JSplitPane jsp = new JSplitPane(0, getTablePanel(), getTabbedPanel());
        jsp.setDividerLocation(300);
        add(jsp, "Center");
    }

    @Override
    public void reload() {
        // TODO Auto-generated method stub

    }

    public void itemStateChanged(ItemEvent e) {
        if (e.getSource().equals(this.teamForNPlayerCBB)) {

            getModel().getTeamForNPlayerModel().setTeamMateNumberByTeam(((Integer) this.teamForNPlayerCBB.getSelectedItem()).intValue());

            Object[] args = { (Integer) this.teamForNPlayerCBB.getSelectedItem() };
            this.organizeTeamForNPlayer.setText(new MessageFormat(teamForNPlayerLB).format(args));

        } else if (e.getSource().equals(this.playerForNTeamCBB)) {

            Object[] args = { (Integer) this.playerForNTeamCBB.getSelectedItem() };
            this.organizePlayerForNTeam.setText(new MessageFormat(playerForNTeamLB).format(args));
            // getModel().getTeamForNPlayerModel().setTeamMateNumberByTeam((Integer)equipeDeN.getSelectedItem());

        }

    }
}
